import React, { Component } from "react";
import { Link,withRouter } from "react-router-dom";
import { Menu } from "antd";
import { Icon } from '@ant-design/compatible';//兼容antd4.x图标
import "./index.less";
import logo from "../../assets/images/react.png";
import menuList from "../../config/menuConfig";
import memoryUtils from '../../utils/memoryUtils.js';
import storageUtils from '../../utils/storageUtils';

const { SubMenu } = Menu;

class LeftNav extends Component {

  /**
   * 根据menu的数据数组生成对应的标签数组
   * 使用map()+递归调用
   * @param { 菜单数组 } menuList
   */
  getMenuNodes = (menuList) => {

    //得到当前请求的路由路径
    const path = this.props.location.pathname;

    return menuList.map((item) => {
      if (!item.children) {
        return (
          <Menu.Item key={item.key}>
            <Link to={item.key}>
              <Icon type={item.icon} />
              <span>{item.title}</span>
            </Link>
          </Menu.Item>
        );
      } else {
        const cItem = item.children.find(cItem => cItem.key === path);
        if(cItem){
          this.openKey = item.key;
        }

        return (
          <SubMenu
            key={item.key}
            title={
              <span>
                <Icon type={item.icon} />
                <span>{item.title}</span>
              </span>
            }
          >
            {/* 递归调用生成子级 */}
            {this.getMenuNodes(item.children)}
          </SubMenu>
        );
      }
    });
  };



  // reduce通常用来做累计累加
  /**
   * 根据menu的数据数组生成对应的标签数组
   * 使用reduce()+递归调用
   * @param { 菜单数组 } menuList
   */
  getMenuNodeReduce = (menuList) => {

    //得到当前请求的路由路径
    const path = this.props.location.pathname;

    // 初始值为空数组
    // pre为上一次统计的结果
    // item为当前循环项
    return menuList.reduce((pre, item) => {
      
      // 如果当前用户有item对应的权限,才显示对应菜单项
      if(this.hasAuth(item)){
        // 向pre添加<Menu.Item></Menu.Item>
        if(!item.children){
          pre.push((
            <Menu.Item key={item.key}>
              <Link to={item.key}>
                <Icon type={item.icon} />
                <span>{item.title}</span>
              </Link>
            </Menu.Item>
          ));
        }else{
          // 查找子项，用于选中子菜单效果
          // 通过匹配子项菜单的key和地址栏上的path来进行选中效果
          const cItem = item.children.find(cItem => path.indexOf(cItem.key) === 0);
          if(cItem){
            this.openKey = item.key;
          }
          // 向pre添加<SubMenu></SubMenu>
          pre.push((
            <SubMenu
              key={item.key}
              title={
                <span>
                  <Icon type={item.icon} />
                  <span>{item.title}</span>
                </span>
              }
            >
              {/* 递归调用生成子级 */}
              {this.getMenuNodeReduce(item.children)}
            </SubMenu>
          ));
        }
      }

      return pre;

    }, []);
  }

  
  
  /**
   * 根据用户角色所拥有的权限，判断是否显示该菜单项
   */
  hasAuth = (item) => {
    // 1.如果当前用户是admin,直接全部权限
    // 2.如果当前item是公开的
    // 3.当前用户有此item权限：key有没有对应menu
    const { key, isPublic } = item;
    const { menus } = memoryUtils.user.role;
    const { username } =  memoryUtils.user;

    if(username === 'admin' || isPublic || menus.indexOf(key) !== -1){
      return true;
    }else if(item.children){
      // 如果当前用户有此item的某个字item权限
      return !!item.children.find(v => menus.indexOf(v.key) !== -1);

    }

    return false;
  }


  // 在第一次render()之前执行一次
  UNSAFE_componentWillMount(){
    // 从这里获取到处理后的菜单

    // 使用map()+递归调用
    // this.menuNodes = this.getMenuNodes(menuList);

    // 使用reduce()+递归调用
    this.menuNodes = this.getMenuNodeReduce(menuList);

  }

  render() {
    // 从浏览器地址栏改路径后的选中菜单效果
    //得到当前请求的路由路径
    let path = this.props.location.pathname;

    if(path.indexOf('/product') === 0){
      path = '/product';
    }

    // 得到需要打开的菜单项
    const openKey = this.openKey;

    return (
      <div className="left-nav">
        <Link to="/" className="left-nav-header">
          <img src={logo} alt="REACT" />
          <h1>REACT后台</h1>
        </Link>

        <Menu 
        mode="inline" 
        theme="dark"
        selectedKeys={[path]}
        defaultOpenKeys={[openKey]}
        >
          {this.menuNodes}
        </Menu>
      </div>
    );
  }
}

/**
 * withRouter 高阶组件
 * 包装非路由组件，返回一个新组件
 * 新的组件向非路由组件传递3个属性：history/location/match
 */
export default withRouter(LeftNav);
